{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "## Python 模块"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python模块是一个比较常用的功能，模块类似于Java中的jar包，是一个将部分程序功能通过打包的形式包装成一个整体的形式，然后便于我们在需要使用的场景直接通过引用模块来实现功能，降低代码的耦合性，增加代码的复用性。模块的使用可以通过使用**from**关键字和**import**关键字,如下给出一个简单的小例子:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "system path: ['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client', '/usr/lib/python2.7/dist-packages/wx-2.8-gtk2-unicode', '/usr/local/lib/python2.7/dist-packages/IPython/extensions', '/home/caihaifei/.ipython']\n",
      "Tue Dec  5 13:17:53 2017\n",
      "\n",
      "\n",
      "[4, 5, 0, 3, 8, 1, 9, 6, 2, 7]\n",
      "deque([45, 4, 5, 0, 3, 8, 1, 9, 6, 2, 7])\n",
      "deque([0, 3, 8, 1, 9, 6, 2, 7, 45, 4, 5])\n"
     ]
    }
   ],
   "source": [
    "#通过import直接导入模块.\n",
    "import sys,time\n",
    "#通过from module import  function 导入random 模块中的shuffle函数.\n",
    "from random import shuffle\n",
    "#通过from module import * 导入collections模块的所有公开API.\n",
    "from collections import *\n",
    "\n",
    "\n",
    "#导入的sys模块的特性使用\n",
    "print \"system path:\",sys.path\n",
    "print time.asctime()\n",
    "#导入的shuffle的使用，shuffle可以将序列随机打乱\n",
    "list=[1,2,3,4,5,6,7,8,9,0]\n",
    "shuffle(list)\n",
    "print \"\\n\\n\",list\n",
    "#导入的collection模块\n",
    "q=deque(list)\n",
    "q.append(12)\n",
    "q.appendleft(45)\n",
    "q.pop()\n",
    "print q\n",
    "q.rotate(-3)\n",
    "print q "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如上为简单使用的几个python自带的模块的使用示例。其中导入的模块之间或者模块的属性之间可以通过***，**来连接.通过**import**直接导入的模块使用其内部的属性或函数等的时候需要使用**moduleName.beahavior**来调用，而通过**from moudle import name**  方式调用的模块可以直接通过属性名称使用而不需要指定模块名称.如下，通过几个方面来了解模块的使用以及创建。\n",
    "\n",
    "- [模块的创建](#1)\n",
    "- [包与模块](#2)\n",
    "- [模块中的一些魔法属性以及模块的使用说明](#3)\n",
    "- [python中的自带常用模块的使用](#4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <a name=\"1\">模块的创建</a>\n",
    "\n",
    "\n",
    "模块的创建其实就是创建一个py文件，让其可以通过在py文件中定义一些诸如“类、属性、函数\"等，然后通过在另一个脚本文件(*.py)中导入执行或者直接通过命令行命令执行。如下根据一个简单的示例来介绍模块的创建过程.\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#caculator.py\n",
    "\n",
    "#!/usr/bin/env python\n",
    "# -*- encoding:utf-8 -*-\n",
    "\n",
    "import sys\n",
    "\n",
    "def addition(*args):\n",
    "    \"\"\"\n",
    "    Addition Operation.\n",
    "    :param args:  All the operands.\n",
    "    :return: the result of operation.\n",
    "    \"\"\"\n",
    "    if len(args) > 0:\n",
    "        result = args[0]\n",
    "        try:\n",
    "            for operand in args[1:]:\n",
    "                result += operand\n",
    "        except Exception as e:\n",
    "            print str(e)\n",
    "            pass\n",
    "        return result\n",
    "    else:\n",
    "        print \"args must not be empty.\"\n",
    "        raise Exception(\"args must not be empty.\")\n",
    "\n",
    "\n",
    "def subtraction(*args):\n",
    "    \"\"\"\n",
    "    Subtraction Operation.\n",
    "    :param args: All the operands.\n",
    "    :return: the result of operation.\n",
    "    \"\"\"\n",
    "    if len(args) > 0:\n",
    "        result = args[0]\n",
    "        try:\n",
    "            for operand in args[1:]:\n",
    "                result -= operand\n",
    "        except Exception as e:\n",
    "            print str(e)\n",
    "            pass\n",
    "        return result\n",
    "    else:\n",
    "        print \"args must not be empty.\"\n",
    "        raise Exception(\"args must not be empty.\")\n",
    "\n",
    "\n",
    "def monocular(operator, *args):\n",
    "    \"\"\"\n",
    "     Simple Operation\n",
    "    :param operator:  Operator for monocular operations\n",
    "    :param args: All the operands.\n",
    "    :return:the result of operation.\n",
    "    \"\"\"\n",
    "    if len(args) > 0:\n",
    "         result = float(args[0])\n",
    "        try:\n",
    "            for operand in args[1:]:\n",
    "                if operator in \"+\":\n",
    "                    result += float(operand)\n",
    "                elif operator in '-':\n",
    "                    result -= float(operand)\n",
    "                elif operator in '*':\n",
    "                    result *= float(operand)\n",
    "                elif operator in '/':\n",
    "                    result /= float(operand)\n",
    "        except Exception as e:\n",
    "            print str(e)\n",
    "            pass\n",
    "        return result\n",
    "    else:\n",
    "        print \"args must not be empty.\"\n",
    "        raise Exception(\"args must not be empty.\")\n",
    "\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    \"\"\"\n",
    "      By  external call.\n",
    "    \"\"\"\n",
    "    print \"main step.\"\n",
    "    # args of used.\n",
    "    if len(sys.argv) >= 4:\n",
    "        print sys.argv\n",
    "        args = sys.argv[1:]\n",
    "        result = monocular(args[0], *(args[1:]))\n",
    "         print \"get result:\", result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "15\n"
     ]
    }
   ],
   "source": [
    "import calculator,sys\n",
    "\n",
    "#设置模块文件加载的路径\n",
    "sys.path.append('../')\n",
    "print calculator.monocular(\"/\",46,3)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如上，为一个简单的单目计算器，提供了单独的计算加法、减法和通过指定运算符号（\"+\"、“-”、“*”、“/”）来计算结果，如上所示,上面通过**sys.path**添加模块位置。通过**import**导入caculator可以直接使用calculator中的计算方法。**caculator**中页提供了直接传入参数的方法，使用如下:\n",
    "\n",
    "```\n",
    "caihaifei@hfcai:#  python calculator.py - 12 4\n",
    "['calculator.py', '-', '12', '4']\n",
    "get result: 8.0\n",
    "\n",
    "\n",
    "```\n",
    "\n",
    "\n",
    "如上,通过命令行传入参数,py中通过导入sys模块，对输入参数通过sys.args进行接收,接受对象为一个list,将参数依照顺传入，然后对参数进行过滤处理，参数参数，回调返回运算结果.综上，可以简单概况模块创建使用的几个步骤:\n",
    "\n",
    "- 创建模块文件(*.py)\n",
    "   这是模块功能执行的核心，需要通过编写逻辑代码完成功能。\n",
    "   \n",
    "- 导入模块\n",
    "   在需要使用模块功能的文件中导入需要使用的模块，通过使用**import**和**from**实现导入。\n",
    "   \n",
    "- 查找模块\n",
    "  导入模块后在使用模块的时候，需要找到对应的模块位置，默认python查找py文件位置在系统设置的path路径中，可以通过**sys**模块中的path追加查找目录。\n",
    "  \n",
    "  \n",
    "- 功能使用\n",
    "\n",
    "   若是通过**import**方式导入的需要通过模块名.功能调用，若是通过**from module import function**导入的可以直接使用对应的特性或函数调用。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <a name=\"2\">包与模块</a>\n",
    "\n",
    "包可以说python中一种特殊的模块形式，包中可以包含多个模块(以py为后缀的单个脚本文件)，同时由于包的隔离也会避免多个不同模块的重名问题，和java中的包有异曲同工之妙。python中的包的结构有两个部分组成：一个是包的识别文件，任意一个python包中均需要包含一个定义包的文件(__init__.py)在包的根目录下(且需要注意的是对于python中的包而言，每个层次的文件夹下均需要包含**__init__.py**文件用于申明包的合法地位);另一个部分就是包中包含的子模块，python中需要将一个模块添加到一个包内，仅仅需要将该模块文件(可以是一个包也可以是一个py文件)添加到包的文件夹目录下即可。如下，为一个简单的包的结构形式展示:\n",
    "\n",
    "\n",
    "```\n",
    "package-dir-\n",
    "     ---- __init__.py  #包模块定义文件，可以不包含任何内容，但文件一定需要存在.\n",
    "     ----package_A\n",
    "          ---- __init__.py #子包中的定义文件\n",
    "          ----A.py   #package_A的子模块文件\n",
    "          ----B.py\n",
    "     ----A.py   * pacakge-dir-的自模块文件\n",
    "     ----B.py\n",
    "     ----C.py\n",
    "\n",
    "```\n",
    "\n",
    "对于包模块的使用和一般的模块使用类似，对于包模块而言，模块名即是包名，对于包内的自模块的使用可以通过使用**包名.模块名**来使用。使用如\n",
    "下示例:\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import smtplib\n",
    "from email.mime.text import MIMEText  \n",
    "from email.header import Header\n",
    "\n",
    "# Create a text/plain message\n",
    "msg = MIMEText('测试文本...', 'plain', 'utf-8')\n",
    "\n",
    "me = 'root@enjoytoday.cn'\n",
    "you = 'caihaifei@enjoytoday.cn'\n",
    "msg['Subject'] = Header('The contents of %s' % msg,'utf-8')\n",
    "msg['From'] = Header(me,'utf-8')\n",
    "msg['To'] = Header(you,'utf-8')\n",
    "\n",
    "try:\n",
    "    s = smtplib.SMTP('localhost')\n",
    "    s.sendmail(me, [you], msg.as_string())\n",
    "    print (\"邮件发送成功-----------------\")\n",
    "    s.quit()\n",
    "except smtplib.SMTPException as e:\n",
    "    error=\"无法发送邮件：\",e\n",
    "    print(error)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如上为一个使用Python邮件处理的包发送邮件的示例，但一般不一定能发送成功需要做一些必要的处理，这里主要是通过其看包的使用，如上包为**email**，其中**mime**为其中的一个包模块，**header**为其中的一个普通模块，**text**为**mine**内的一个模块，导入如上通过:\n",
    "\n",
    "```\n",
    "from package.module import function\n",
    "from package.module import *\n",
    "\n",
    "```\n",
    "\n",
    "\n",
    "通过上面的格式导入一个包内的模块的函数和特性，导入完成后的使用和一般模块并没有什么不一样."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <a name=\"3\">模块中的一些魔法属性以及模块的使用说明</a>\n",
    "\n",
    "python中的标准模块和三方模块都较多。所以学会如何去查看一个模块的基本信息以及掌握如何使用就显得很重要，一般可以通过网上的教程和文档去了解使用，同时也可以通过对模块内部的文档和属性说明进行了解。\n",
    "\n",
    "- 文档说明\n",
    "\n",
    "可以通过模块提供的注解文档进行了解模块的使用，文档的获取可以通过两种方式获取:一种是通过内建函数help获取，一种通过文档内的**__doc__**魔法属性进行了解。如下，为对**email**模块的注释文档信息获取.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "help get info:\n",
      "Help on package email:\n",
      "\n",
      "NAME\n",
      "    email - A package for parsing, handling, and generating email messages.\n",
      "\n",
      "FILE\n",
      "    /home/hfcai/anaconda3/envs/py2/lib/python2.7/email/__init__.py\n",
      "\n",
      "MODULE DOCS\n",
      "    https://docs.python.org/library/email\n",
      "\n",
      "PACKAGE CONTENTS\n",
      "    _parseaddr\n",
      "    base64mime\n",
      "    charset\n",
      "    encoders\n",
      "    errors\n",
      "    feedparser\n",
      "    generator\n",
      "    header\n",
      "    iterators\n",
      "    message\n",
      "    mime (package)\n",
      "    parser\n",
      "    quoprimime\n",
      "    utils\n",
      "\n",
      "FUNCTIONS\n",
      "    message_from_file(fp, *args, **kws)\n",
      "        Read a file and parse its contents into a Message object model.\n",
      "        \n",
      "        Optional _class and strict are passed to the Parser constructor.\n",
      "    \n",
      "    message_from_string(s, *args, **kws)\n",
      "        Parse a string into a Message object model.\n",
      "        \n",
      "        Optional _class and strict are passed to the Parser constructor.\n",
      "\n",
      "DATA\n",
      "    Charset = <email.LazyImporter object>\n",
      "    Encoders = <email.LazyImporter object>\n",
      "    Errors = <email.LazyImporter object>\n",
      "    Generator = <email.LazyImporter object>\n",
      "    Header = <email.LazyImporter object>\n",
      "    Iterators = <email.LazyImporter object>\n",
      "    MIMEAudio = <email.LazyImporter object>\n",
      "    MIMEBase = <email.LazyImporter object>\n",
      "    MIMEImage = <email.LazyImporter object>\n",
      "    MIMEMessage = <email.LazyImporter object>\n",
      "    MIMEMultipart = <email.LazyImporter object>\n",
      "    MIMENonMultipart = <email.LazyImporter object>\n",
      "    MIMEText = <email.LazyImporter object>\n",
      "    Message = <email.LazyImporter object>\n",
      "    Parser = <email.LazyImporter object>\n",
      "    Utils = <email.LazyImporter object>\n",
      "    __all__ = ['base64MIME', 'Charset', 'Encoders', 'Errors', 'Generator',...\n",
      "    __version__ = '4.0.3'\n",
      "    base64MIME = <email.LazyImporter object>\n",
      "    quopriMIME = <email.LazyImporter object>\n",
      "\n",
      "VERSION\n",
      "    4.0.3\n",
      "\n",
      "\n",
      "\n",
      "\n",
      " __doc__  info:\n",
      "A package for parsing, handling, and generating email messages.\n"
     ]
    }
   ],
   "source": [
    "import email\n",
    "\n",
    "print \"help get info:\"\n",
    "help(email)\n",
    "print \"\\n\\n __doc__  info:\"\n",
    "print email.__doc__\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如上，发现明显的help可以获取更多的信息，而相对的**__doc__**可能比较随意，只是一些简单的描述。\n",
    "\n",
    "- 基本的使用功能\n",
    "\n",
    "为了更快的掌握模块的使用，可能需要尽量的了解比较常用的功能(类和函数等)，这样可以节约不少时间,python中为此也提供了几种方式帮助我妈快速了解整个模块的功能结果。一样的，这个也提供两种方式，一种属于python中自动生成处理的(dir())，一个是人工手动设置的(__all__)，使用如下:\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dir of email: ['Charset', 'Encoders', 'Errors', 'FeedParser', 'Generator', 'Header', 'Iterators', 'LazyImporter', 'MIMEAudio', 'MIMEBase', 'MIMEImage', 'MIMEMessage', 'MIMEMultipart', 'MIMENonMultipart', 'MIMEText', 'Message', 'Parser', 'Utils', '_LOWERNAMES', '_MIMENAMES', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', '__version__', '_name', '_parseaddr', 'base64MIME', 'base64mime', 'charset', 'email', 'encoders', 'errors', 'feedparser', 'generator', 'header', 'importer', 'iterators', 'message', 'message_from_file', 'message_from_string', 'mime', 'parser', 'quopriMIME', 'quoprimime', 'sys', 'utils']\n",
      "\n",
      "\n",
      " email usually functions: ['base64MIME', 'Charset', 'Encoders', 'Errors', 'Generator', 'Header', 'Iterators', 'Message', 'MIMEAudio', 'MIMEBase', 'MIMEImage', 'MIMEMessage', 'MIMEMultipart', 'MIMENonMultipart', 'MIMEText', 'Parser', 'quopriMIME', 'Utils', 'message_from_string', 'message_from_file', 'base64mime', 'charset', 'encoders', 'errors', 'generator', 'header', 'iterators', 'message', 'mime', 'parser', 'quoprimime', 'utils']\n"
     ]
    }
   ],
   "source": [
    "import email\n",
    "\n",
    "print \"dir of email:\",dir(email)\n",
    "\n",
    "print \"\\n\\n email usually functions:\",email.__all__"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "一般情况下会将模块中的所有方法属性信息都列出来，看起来比较难以多(包含许多我们并不需要的信息如魔法属性等)，而__all__为模块创建者为了提供的公有API接口，具有较大的参考性.\n",
    "\n",
    "- 模块源码\n",
    "\n",
    "最最有效的方式但往往也是最浪费时间的方法，直接看模块的源代码来推理逻辑，这个会对模块的结构更加详细的了解，但需要花费较大的精力，python中提供了**__file__**属性来帮助我们查看源码，如下:\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'/home/hfcai/anaconda3/envs/py2/lib/python2.7/email/__init__.pyc'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import email\n",
    "\n",
    "email.__file__"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "该属性会输出源码的文件位置(包类型的模块指定的位置为对应的**__init__.py**文件)，可以直接查看源码或者复制代码，一般输出的文件类型为*.py或者*.pyc"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <a name=\"4\">python中的自带常用模块的使用</a>\n",
    "\n",
    "\n",
    "python中自带了许多标准的模块来帮助我们处理一些基础的功能。如实现时间的处理的time、常用的sys模块、操作系统服务访问模块os、文件操作模块fileinput模块和网络处理模块urllib和urllib2等。这些模块可以实现一些比较重要的和复杂的事，让我们更加专注与具体事务的处理。模块的具体使用方法和模块功能介绍可以通过python的library文档进行了解和使用，地址为:https://docs.python.org/2/library/index.html\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
